﻿/* 程序：被动式无人机检测主程序
 * 版本：1.01
 * 说明：基于RT5350的WiFi数据包抓取和MAC地址，通过MAC地址段匹配检测无人机
 * 网站：https://gitee.com/violick/WuRenJiJianCe.git
 * 作者：闵行中学 高二（5）班 谈知行
 * 修改时间：2017.12.01
*/
 

using System;
using System.IO;
using System.Xml.Linq;
using System.Collections.Generic;
using System.Globalization;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using UltraSystemLib;

namespace WiFiScan
{
    public partial class WiFiScaner : Form
    {
        public WiFiScaner()
        {
            InitializeComponent();
        }

        private Comm comm;  // 串口接收类
        private UavCapture uavCapture;   // 无人机判别处理类
        private void OnFormLoaded(object sender, EventArgs e)
        {
            // 设置ListView样式
            listUavs.FullRowSelect = true;      // 整行选取
            listUavs.View = View.Details;       // 详细列表

            // 设置各列标题、宽度、文本对齐方式
            listUavs.Columns.Add("配对", 60, HorizontalAlignment.Center);
            listUavs.Columns.Add("平台类型", 80, HorizontalAlignment.Center);
            listUavs.Columns.Add("捕获时间", 120, HorizontalAlignment.Center);
            listUavs.Columns.Add("在线状态", 80, HorizontalAlignment.Center);
            listUavs.Columns.Add("信号强度", 80, HorizontalAlignment.Center);
            listUavs.Columns.Add("身份ID（MAC）", 120, HorizontalAlignment.Center);
            listUavs.Columns.Add("制造商", 300, HorizontalAlignment.Left);

            // 设置ListView绘制方式
            listUavs.OwnerDraw = true;          // 设置用户代码绘制属性
            listUavs.DrawItem += new DrawListViewItemEventHandler(listUavs_DrawItem);   // 设置用户Item绘制方法入口
            listUavs.DrawSubItem += new DrawListViewSubItemEventHandler(listUavs_DrawSubItem);  // 设置用户SubItem绘制方法入口
            listUavs.DrawColumnHeader += new DrawListViewColumnHeaderEventHandler(listUavs_DrawColumnHeader);   // // 设置用户Header绘制方法入口
            listUavs.Font = new Font("宋体", 8, FontStyle.Bold);     

            uavCapture = new UavCapture();    // 创建无人机判别处理类

            comm = new Comm(0, "COM1", 57600, OnCommDataReceived);      // 设置串口参数
            if (!comm.OpenPort())   // 打开串口设备
            {
                MessageBox.Show("Open COM1 failed.");
                return;
            }
            uavCapture.GetAPState();
        }
        // ListView items 绘制背景
        private void listUavs_DrawItem(object sender /*需要绘制的ListView*/, DrawListViewItemEventArgs e/*需要绘制的Item*/)
        {
            if (e.ItemIndex % 2 == 0)
            {
                e.Graphics.FillRectangle(Brushes.LightGray, e.Bounds);  // 偶数行绘制灰色背景
            }
            else
            {
                e.Graphics.FillRectangle(Brushes.White, e.Bounds);      // 奇数行绘制白色背景
            }
            if ((e.State & ListViewItemStates.Selected) != 0)
            {
                e.DrawFocusRectangle(); // 选中行绘制虚线边框
            }
        }

        // subitem 绘制格式化文本
        private void listUavs_DrawSubItem(object sender, DrawListViewSubItemEventArgs e/*需要绘制的SubItem*/)
        {
            using (StringFormat sf = new StringFormat())
            {
                // 设置SubItem文本对齐方式.
                sf.LineAlignment = StringAlignment.Center;  //垂直居中
                switch (e.Header.TextAlign)
                {
                    case HorizontalAlignment.Center:
                        sf.Alignment = StringAlignment.Center;      // 水平居中
                        break;
                    case HorizontalAlignment.Right:                 // 右对齐
                        sf.Alignment = StringAlignment.Far;         // 右对齐
                        break;
                    default:
                        sf.Alignment = StringAlignment.Near;        // 左对齐
                        break;
                }
                if (e.Header.Text.Equals("信号强度"))   // 信号强度使用红色警戒色
                {
                    e.Graphics.DrawString(e.SubItem.Text + "dB", listUavs.Font, Brushes.Red, e.Bounds, sf);
                }
                else
                {
                    e.Graphics.DrawString(e.SubItem.Text, listUavs.Font, Brushes.Black, e.Bounds, sf);
                }
            }
        }

        // 绘制表头行
        private void listUavs_DrawColumnHeader(object sender, DrawListViewColumnHeaderEventArgs e)
        {
            using (StringFormat sf = new StringFormat())
            {
                // 设置表头对齐格式
                sf.Alignment = StringAlignment.Center;      // 水平居中
                sf.LineAlignment = StringAlignment.Center;  // 垂直居中

                // 绘制标准的表头背景
                e.Graphics.FillRectangle(Brushes.Black, e.Bounds);  // 表头行绘制黑色背景

                // 绘制表头文本
                using (Font headerFont = new Font("Helvetica", 8, FontStyle.Bold))
                {
                    e.Graphics.DrawString(e.Header.Text, headerFont, Brushes.White, e.Bounds, sf);
                }
            }
            return;
        }

        private BinaryWriter bw;
        void OnCommDataReceived(UInt32 id, NetEvent netEvent, object[] paraments)   // 串口数据接收通知函数
        {
            if (netEvent == NetEvent.DataReceived)
            {
                if (checkSaveData.Checked)
                {
                    if (bw == null)
                    {
                        bw = new BinaryWriter(File.Create("data.txt"));
                    }
                    bw.Write(paraments[0] as byte[]);
                }
                else
                {
                    if (bw != null)
                    {
                        bw.Close();
                        bw = null;
                    }
                }
                uavCapture.OnComDataIn(paraments[0] as byte[]);   // 串口数据解析
            }
        }
        private bool startSeeking = false;
        private void OnStartScan(object sender, EventArgs e)    // 开始/停止搜索模式
        {
            if (buttonScan.Text.Equals("扫描"))   
            {
                buttonScan.Text = "停止";
                
                startSeeking = true;
                uavCapture.DispalyAll = checkDispalyAll.Checked;
                comm.SendData(uavCapture.ScanAP());
            }
            else
            {
                startSeeking = false;
                buttonScan.Text = "扫描";
            }
        }
        private int scanTimerCount = 0;
        private void OnTimerTicks(object sender, EventArgs e)   // 定时器函数
        {
            if (comm != null)
            {
                if (startSeeking)
                {
                    if (scanTimerCount++ == 0)
                    {
                        //comm.SendData(uavCapture.SetChannel(++uavCapture.ChannelSelected));     // 搜索下一个信道
                        if (uavCapture.ChannelSelected > 14)
                        {
                            uavCapture.ChannelSelected = 0;
                        }
                    }
                    else if (scanTimerCount >= 9)
                    {
                        scanTimerCount = 0;
                    }
                }
            }
            labelFramesCount.Text = uavCapture.FramesCount.ToString();  // 显示接收到的总帧数

            if (uavCapture.MsgReceived != null )
            {
                do
                {
                    string message;
                    uavCapture.MsgReceived.TryDequeue(out message); // 读取接收到的消息
                    if (message == null)
                    {
                        break;
                    }
                    if (checkPause.Checked)
                    {
                        continue;
                    }
                    textFrames.Text += message;     // 显示消息
                } while (true);
                
                if (!checkPause.Checked)
                {
                    textFrames.SelectionStart = textFrames.Text.Length; //获取textBox1内容长度
                    textFrames.ScrollToCaret(); // 将控件内容滚动到当前插入符号位置
                }
            }       // 显示AP模块的的消息和数据包

            UpdateUavsState();      // 更新无人机的最新检测状态
        }

        void UpdateUavsState()
        {
            for (int i = 0; i < listUavs.Items.Count; i++)      // 遍历整个无人机列表，更新已发现目标状态
            {
                var mac = UInt64.Parse(listUavs.Items[i].SubItems[5].Text, NumberStyles.HexNumber);     // 读取MAC地址列

                if (uavCapture.Uavs.ContainsKey(mac))       // 查询MAC匹配无人机的参数
                {
                    // 更新无人机列表数据
                    var uav = uavCapture.Uavs[mac];
                    if (uav.State == UavState.Online)
                    {
                        var span = DateTime.Now - uav.DetectedTime;
                        if (span.TotalSeconds > 60)     // 超过1分钟无数据，将目标状态置为下线
                        {
                            uav.State = UavState.Offline;
                        }

                        listUavs.Items[i].SubItems[0].Text = uav.Number.ToString();
                        listUavs.Items[i].SubItems[2].Text = uav.DetectedTime.ToLongTimeString();
                        listUavs.Items[i].SubItems[3].Text = uav.State.ToString();
                        listUavs.Items[i].SubItems[4].Text = uav.SignalStrenth.ToString();
                    }
                }
                else
                {
                    MessageBox.Show("目标不存在， MAC：" + mac.ToString("X12"));
                }
            }

            foreach (var uav in uavCapture.Uavs.Values.Where(item => item.NewTargetFlag))   //查询新发现目标
            {
                listUavs.Items.Add(new ListViewItem(new string[]    // 在无人机列表中增加新项
                {
                        uav.Number.ToString(),
                        uav.Type.ToString(),
                        uav.DetectedTime.ToLongTimeString(),
                        uav.State.ToString(),
                        uav.SignalStrenth.ToString(),
                        uav.Mac.ToString("X12"),
                        uav.Manufacturer
                }));
                uav.NewTargetFlag = false;      // 取消新目标标志
            }
        }

        private void OnTest(object sender, EventArgs e) // 本地文件测试函数
        {
            uavCapture.Test();
        }

        private void OnLockon(object sender, EventArgs e)       // 锁定目标
        {
            comm.SendData(uavCapture.SetChannel(11));
        }

        private void OnClearScreen(object sender, EventArgs e)
        {
            textFrames.Text = string.Empty;
        }

        private void OnFormClosed(object sender, FormClosedEventArgs e)
        {
            if (comm != null)
            {
                comm.ClosePort();   // 关闭串口
            }
        }

        private void OnDispalyAll(object sender, EventArgs e)
        {
            if (uavCapture != null)
            {
                uavCapture.DispalyAll = checkDispalyAll.Checked;
            }
        }
    }
}

